package com.hxgis.common.utils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 反射提取值
 */
public class RectField {




    /**
     * 反射提取集合的值
     * @param <T>
     * @return
     */
    public static <T> List<T>  getBeanFields(Collection collection,String fieldName){
        if (!CollectionUtils.isNotBlank(collection)){
            return null;
        }
        List<T> tList = new ArrayList<T>();
        for (Object o : collection) {
            T beanField = getBeanField(o, fieldName);
            if (beanField!= null) tList.add(beanField);
        }
        return tList;
    }


    /**
     *  提取数据 进行索引
     * @param collection
     * @param fieldName
     * @param <M>
     * @param <T>
     * @return
     */
    public static <M,T> Map<M,T> conversionIndex(Collection<T> collection, String fieldName){
        Map<M,T> indexMap = new HashMap<M, T>();
        for (T t : collection) {
            M index = getBeanField(t, fieldName);
            if (index != null) indexMap.put(index,t);
        }
        return indexMap;
    }


    /**
     *  提取数据 进行索引
     * @param collection
     * @param fieldNames
     * @param <M>
     * @param <T>
     * @return
     */
    public static <M,T> Map<M, List<T>> conversionIndexToList(Collection<T> collection,String... fieldNames){
        Map<M,List<T>> indexMap = new HashMap<M, List<T>>();
        if (fieldNames == null|| fieldNames.length == 0){
            return indexMap;
        }
        for (T t : collection) {
            M index = getBeanFields(t, fieldNames);
            List<T> ts = indexMap.get(index);
            if (ts == null){
                ts = new ArrayList<T>();
                indexMap.put(index,ts);
            }
            ts.add(t);
        }
//        return indexMap;
        return indexMap;
    }




    /**
     * 使用多个字段作为索引
     * @param collection
     * @param fieldNames
     * @param <M>
     * @param <T>
     * @return
     */
    public static <M,T> Map<M,T> conversionIndex(Collection<T> collection, String... fieldNames){
        Map<M,T> indexMap = new HashMap<M, T>();
        if (!CollectionUtils.isNotBlank(collection)){
            return indexMap;
        }
        for (T t : collection) {
            M index = getBeanFields(t, fieldNames);
            if (index != null) indexMap.put(index,t);
        }
        return indexMap;
    }

    /**
     * 根据字段取值
     * @param o
     * @param fieldNames
     * @param <T>
     * @return
     */
    public static <T> T  getBeanFields(Object o,String ... fieldNames){
        if (o instanceof Map){
            String[] ret = new String[fieldNames.length];
            for (int i=0;i<fieldNames.length;i++) {
                Object v = ((Map) o).get(fieldNames[i]);
                if (v == null){
                    continue;
                }
                ret[i] = v.toString();
//                ret = ret+"="+ declaredField.get(o).toString();
            }
            String rets = StringUtils.join(ret,"=");
            return (T) rets;
        }
        Class<?> aClass = o.getClass();
        try {
            String[] ret = new String[fieldNames.length];
            for (int i=0;i<fieldNames.length;i++) {
                Field declaredField = getFieldSupper(fieldNames[i],aClass);
                if (declaredField == null){
                    continue;
                }
                declaredField.setAccessible(true);
                if( declaredField.get(o) == null){
                    return null;
                }
                ret[i] = declaredField.get(o).toString();
//                ret = ret+"="+ declaredField.get(o).toString();
            }
            String rets = StringUtils.join(ret,"=");
            return (T) rets;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  null;
    }

    /**
     * 根据字段取值
     * @param o
     * @param fieldName
     * @param <T>
     * @return
     */
    public static <T> T  getBeanField(Object o,String fieldName){
        if (o instanceof Map){
            return (T) ((Map) o).get(fieldName);
        }
        Class<?> aClass = o.getClass();
        try {
            Field declaredField =getFieldSupper(fieldName,aClass);
            if (declaredField == null){
                return null;
            }
            declaredField.setAccessible(true);
           return (T) declaredField.get(o);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  null;
    }


    /**
     * 移除集合中 不符合规则的数据
     * @param m
     * @param fieldName
     * @param flag
     * @param <M>
     * @param <T>
     * @return
     */
    public static <M extends Collection<T>,T> M removeIsNullField(M m,String fieldName,String flag){
        if (!CollectionUtils.isNotBlank(m)){
            return m;
        }
        for (Iterator<T> iterator= m.iterator();iterator.hasNext();){
            T next = iterator.next();
            if (isFieldFlag(next, fieldName, flag)){
                iterator.remove();
            }
        }
        return m;
    }

    /**
     * 看值是否和标识符一样
     * @return
     */
    public static <T> boolean isFieldFlag(T t,String fieldName,String flag){
        Class aClass = t.getClass();
        try {
            Field declaredField =getFieldSupper(fieldName,aClass);
            if (declaredField == null){
                return false;
            }
            declaredField.setAccessible(true);
            Object o = declaredField.get(t);
            return Objects.equals(flag,o);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取包括父类在内的指定字段
     * @param fieldName
     * @param clazz
     * @return
     */
    public static Field getFieldSupper(String fieldName,Class clazz){
        Field declaredField = null;
        try {
            declaredField =  clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            clazz = clazz.getSuperclass();
            if (clazz == null){
                return null;
            }
            declaredField = getFieldSupper(fieldName,clazz);
        }
        return declaredField;
    }


    /**
     * 获取包括父类在内
     * @param clazz
     * @return
     */
    public static List<Field> getFieldSuppers(Class clazz){
        List<Field> fieldList = new ArrayList<Field>();
        while (clazz!=null){
            fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        return fieldList;
    }
}
